2024年3月27日 記
はじめに
ラズパイPicoで遊んでみよう!と思い、以前購入していたラズパイPicoと初心者用キットを引っ張り出し、
遊び始めたのですが・・・、ちょっと気になるものがありました。
それはI2C接続の1602LCDです。
このLCDは、インターネットで検索して出てきた配線通りに配線すれば、Pico用のサンプルプログラムで
動かすことができました。実は私、ここまでは昨年の春ぐらいに(画像などの記録として残っているので)
やっていたみたいなのですが、
「気になるもの」には気付きませんでした(いや、気付いていたけど気にしなかっただけかもしれません)。
で、今回やってみたら「ちょっと気になってしまいました」ということで、その「気になった」ことの対策をしてみました。
結論から言いますと、この「対策」は難しかったです。
メカトロニクス(orデジタル回路)の初心者くらいでは、まったく対応できないレベルだと思います。
当時(と言っても今年の1~2月くらいですが)、どの様に接続すればよいかインターネットで検索しまくったのですが、
結局のところ1602LCDは5Vで動作するのですが、その入出力ピンを直接PicoのI/O端子に直接接続しているものしか見つかりませんでした。
その回路図通り接続してPicoに表示プログラムを書き込み、電源を投入すると・・・動作しました。
が、入出力端子の電圧は4Vを超えているような状態でした。
このままでも動いているのでちょっとしたテスト(遊び)程度でしたら問題ないとは思いますが、
「恒久的な回路」とするにはちょっと気持ち悪いですよね。
そこで対策回路を今年(2024年)の2月中旬くらいに作ったので、参考になればと思いまして掲載することにしました。
ちなみにですが、この記事を書く前に何らかの対策記事が載っていないか検索してみたら
【I2Cバス用双方向電圧レベル変換モジュール(PCA9306)】というものを使って対策してある回路図を見つけました。
ですが、それ以外には見当たらなかったので
トランジスタ、ダイオード、抵抗、コンデンサで構成した対策回路をご紹介したいと思います。
目次
(1)回路図と解説
(2)購入品について
(3)C言語プログラム(端子初期化部)
(1)回路図と解説
インターネットで検索して、昨年の春頃に作った(動作した)回路は下図のようなものでした。
使用しているGPIOは私の都合により、サンプルプログラムのデフォルト値とは異なっています。ご注意ください。
ここでは(このページでは)、
I2C0 SDA (21pin) → GPIO16
I2C0 SCL (22pin) → GPIO17
となっております。
サンプルプログラムのデフォルト値はおそらく、
I2C0 SDA (6pin) → GPIO4
I2C0 SCL (7pin) → GPIO5
となってるのではないかと思います。
また電源はラズパイPicoのVBUSが+5Vの出力端子として利用できました。
GNDはすべてラズパイPico基板内で接続されている模様です。
アナログGNDは(33pin)があるようですが、
プログラム側で設定しないとデジタル側と分離されないのかもしれません。
そこら辺までは、まだやったことないので分かりません。
単純にSDAとSCL端子を+5Vに4.7KΩでプルアップしただけの回路です。 これでも動作しますし、おそらくこのままでもラズパイPicoは壊れることなく動作すると思われます。 (保証はできませんが、私の経験から言わせて頂きますと「たぶん大丈夫」だと思います。)
しかし仕様範囲外で使うのは気持ち悪いので、対策をすることにしました。 試行錯誤して作成したレベル変換回路はそれぞれ下図のようなものになりました。
●SDA端子の回路図について解説します。
初めに、SDA端子は双方向(時間とともに入力・出力が変化するデータバス)なのはご理解頂いているでしょうか?。
もし分からないときは I2C の仕様書を確認の上、どの様な通信をしているのかをご理解ください。
そして「双方向」であることをご理解ください。
実はこの回路の前に、ダイオードを取った形で動作しないかTryしたのですが、
最初に1度動いたので「動いた!」と思ったのもつかの間で、次電源入れたら動きませんでした。
何回か電源のON/OFFを繰り返したのですがダメでした。
「仕方なくダイオード(D1,D2)を入れたら動作しするようになりました」という感じでした。
なぜこのように「ダイオードを入れた」のかを理解して頂くには、
ダイオードの片方をそれぞれ取り除いた状態のときの「電流の流れ」と、
入力側の入力回路(入力インピーダンス)、出力側の出力回路(出力インピーダンス)を合わせて想像して頂けると良いと思います。
SDA端子は「双方向」だということも忘れずに、頭に入れて置いて考えてくださいね。
それと「ダイオードを両方取り除いた状態」でも
最初の1度だけですが「動いた!」という事実もありまして、その辺も考慮すると理解が早いかもしれません。
ポイントとしては「おそらく両方(ラズパイPicoと1602LCDの両方)とも、
出力回路はオープンドレインだと思われます。
それに「なんだかよく分からない抵抗(出力側の回路により変化してしまうような抵抗)」で
プルアップされているような感じです。
しかも(ラズパイPico側の)出力インピーダンスの微妙な変化で変化してしまうような代物の様です。
そのような感じでしたので、この回路に辿り着くまでにはそれなりに試行錯誤しました。
●SCL端子の回路図について解説します。
SCL端子は、マスター側が同期クロックを出力する端子で、
スレーブ側が同期クロックを入力する端子です。
つまりSDA端子とは異なりまして「一方方向」であるということをご理解ください。
最初に私はSDA端子と同じ回路で「動く」と考えていたのですが、やってみたらダメでした。
で、次にPNP型トランジスタ1個を使ってレベル変換回路を作ってみたのですが、
こちらも結果的にはダメでした。原因は特定できませんでした。何分相手(1602LCD)の
回路がブラックボックス・・・なので。
ただひとつ言えることは「レベル変換回路」の出力波形が鈍(なま)っているように感じたので、
今度はNPN型トランジスタ2個(1個だともうレベル変換無理!という状態になりました)と
波形を尖らせるためのコンデンサ(スピードアップコンデンサ)を
挿入することにしました。
使用しているトランジスタですが、ここではS9018Hというトランジスタを用いました。 オシロスコープで波形を見た感じですと、 おそらくですが2SC1815当たりでは遅くて動作しないのではないかと思われます。 それとこのS9018Hというトランジスタのピンアサインは、 2SC1815とは異なりますので配線するときにはデータシート等で確認することをお勧めします。
NPN型トランジスタにした理由ですが「どうせ2個トランジスタを使うなら、 使い慣れているNPN型がいい」というだけの理由です。 コンデンサの容量と抵抗値の選定については、過去の経験と勘によるところが大きくて 理論的なものを期待されると「説明できません」ということになります。 この辺もかなりオシロスコープの波形と実際の動作(LCDに表示される内容)を確認しながら・・・ 試行錯誤しました。 ただ抵抗値を小さく(R5,R6=4.7K→2K)に変更した理由であれば説明できます。 これは「電流を沢山流すことで、より高速動作を期待したものです」ということになります。 一般論ですが、より「高速動作」させたい場合には、もっと多くの電流を流した方が高速動作します。
(2)購入品について
使用したパーツについてですが、トランジスタはAmazonで売っていた高速タイプのもので、
入手しやすそうなものをチョイスしました。
その他は手持ちのモノとAmazonで入手しやすそうなモノをチョイスしました。
私は基本的に電子パーツを購入するときはAmazonか秋月電子通商で購入しています。
これらの通販サイトで入手できないようなときには、
他のパーツ屋さん(通販サイト)を利用させて頂いております。
(3)C言語プログラム(端子初期化部)
1602LCD(I2C)のサンプルプログラムのデフォルト値は、
下記のように結線されていると仮定して設定していると思います。
I2C0 SDA → GPIO4 (6pin)(default)
I2C0 SCL → GPIO5 (7pin)(default)
上でご紹介した回路図の端子は、
I2C0 SDA → GPIO16 (21pin)
I2C0 SCL → GPIO17 (22pin)
となっています。
実際に試してみるときには、ご確認ください。
ラズパイPicoのC言語のサンプルプログラムは、I/Oピンを指定する際には
「GPIO番号」で指定しますが、私は最初、これに気付かず勝手に「pin番号」だと思い込みまして
「動かない!」としばらく悩んでしまいました。
まぁ、ご参考まで。